package com.zcily.utils;

/**
 * 10进制和N进制的相互转换(N >= 2 && N <= 36)
 * 参考文档：https://zhuanlan.zhihu.com/p/392781796
 */
public class RadixUtil {

    public static final String X36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public static String radix10To36(long num10) {
        return radix10ToDefined(num10, 36);
    }

    public static String radix10ToDefined(long num10, int radix) {
        if (radix < 2 || radix > 36) {
            throw new RuntimeException("不支持" + radix + "进制的转换");
        }
        String radixString = X36.substring(0, radix);
        StringBuilder res = new StringBuilder();
        long quotient = num10;
        int remainder;
        while (true) {
            remainder = (int) (quotient % radix);
            quotient = quotient / radix;
            res.insert(0, radixString.charAt(remainder));
            if (quotient == 0) {
                break;
            }
        }
        return res.toString();
    }

    public static long radix36To10(String num36) {
        return radixDefinedTo10(num36, 36);
    }

    public static long radixDefinedTo10(String numDefined, int radix) {
        if (radix < 2 || radix > 36) {
            throw new RuntimeException("不支持" + radix + "进制的转换");
        }
        String radixString = X36.substring(0, radix);
        long res = 0;
        int length = numDefined.length();
        int power = length - 1;
        char[] array = numDefined.toCharArray();
        for (int i = 0; i < length; i++) {
            int value = radixString.indexOf(array[i]);
            if (value == -1) {
                throw new RuntimeException("不合法的" + radix + "进制数: " + numDefined);
            }
            res = res + value * (long) Math.pow(radix, power);
            power--;
        }
        return res;
    }

    public static void main(String[] args) {
        System.out.println("38 ======>> " + radix10ToDefined(38, 36));
        System.out.println("12 ======>> " + radixDefinedTo10("12", 36));
        System.out.println("1234567 ======>> " + radix10ToDefined(1234567, 36));
        System.out.println("QGLJ ======>> " + radixDefinedTo10("QGLJ", 36));
    }
}
